#ifndef SWDHOST_CM_H
#define SWDHOST_CM_H

#include <stdint.h>

#include "flash_blob.h"

typedef enum {
    RESET_HOLD,              // Hold target in reset
    RESET_PROGRAM,           // Reset target and setup for flash programming.
    RESET_RUN,               // Reset target and run normally
    NO_DEBUG,                // Disable debug on running target
    DEBUG,                   // Enable debug on running target
    HALT,                    // Halt the target without resetting it
    RUN                      // Resume the target without resetting it
} TARGET_RESET_STATE;

//********************************************************************************
uint8_t swd_init_1(void);
uint8_t swd_off_1(void);
uint8_t swd_init_debug_1(void);
uint8_t swd_read_dp_1(uint8_t adr, uint32_t *val);
uint8_t swd_write_dp_1(uint8_t adr, uint32_t val);
uint8_t swd_read_ap_1(uint32_t adr, uint32_t *val);
uint8_t swd_write_ap_1(uint32_t adr, uint32_t val);
uint8_t swd_read_memory(uint32_t address, uint8_t *data, uint32_t size);
uint8_t swd_write_memory_1(uint32_t address, uint8_t *data, uint32_t size);
uint8_t swd_flash_syscall_exec_1(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
void swd_set_target_reset_hw_1(uint8_t asserted);
uint8_t swd_set_target_state_hw_1(TARGET_RESET_STATE state);
uint8_t swd_set_target_state_sw(TARGET_RESET_STATE state);
uint8_t swd_read_word_1(uint32_t addr, uint32_t *val);
uint8_t swd_write_word_1(uint32_t addr, uint32_t val);
uint8_t swd_read_data_1(uint32_t addr, uint32_t *val);
uint8_t swd_write_data_1(uint32_t address, uint32_t data);

//********************************************************************************
uint8_t swd_init_2(void);
//uint8_t swd_off_1(void);
//uint8_t swd_init_debug_1(void);
uint8_t swd_read_dp_2(uint8_t adr, uint32_t *val);
uint8_t swd_write_dp_2(uint8_t adr, uint32_t val);
uint8_t swd_read_ap_2(uint32_t adr, uint32_t *val);
uint8_t swd_write_ap_2(uint32_t adr, uint32_t val);
uint8_t swd_read_memory_2(uint32_t address, uint8_t *data, uint32_t size);
uint8_t swd_write_memory_2(uint32_t address, uint8_t *data, uint32_t size);
uint8_t swd_flash_syscall_exec_2(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
//void swd_set_target_reset_hw_1(uint8_t asserted);
uint8_t swd_set_target_state_hw_2(TARGET_RESET_STATE state);
//uint8_t swd_set_target_state_sw(TARGET_RESET_STATE state);
uint8_t swd_read_word_2(uint32_t addr, uint32_t *val);
uint8_t swd_write_word_2(uint32_t addr, uint32_t val);
uint8_t swd_read_data_2(uint32_t addr, uint32_t *val);
uint8_t swd_write_data_2(uint32_t address, uint32_t data);

//********************************************************************************
uint8_t swd_init_3(void);
//uint8_t swd_off(void);
//uint8_t swd_init_debug(void);
uint8_t swd_read_dp_3(uint8_t adr, uint32_t *val);
uint8_t swd_write_dp_3(uint8_t adr, uint32_t val);
uint8_t swd_read_ap_3(uint32_t adr, uint32_t *val);
uint8_t swd_write_ap_3(uint32_t adr, uint32_t val);
uint8_t swd_read_memory_3(uint32_t address, uint8_t *data, uint32_t size);
uint8_t swd_write_memory_3(uint32_t address, uint8_t *data, uint32_t size);
uint8_t swd_flash_syscall_exec_3(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
//void swd_set_target_reset_hw(uint8_t asserted);
uint8_t swd_set_target_state_hw_3(TARGET_RESET_STATE state);
//uint8_t swd_set_target_state_sw(TARGET_RESET_STATE state);
uint8_t swd_read_word_3(uint32_t addr, uint32_t *val);
uint8_t swd_write_word_3(uint32_t addr, uint32_t val);
uint8_t swd_read_data_3(uint32_t addr, uint32_t *val);
uint8_t swd_write_data_3(uint32_t address, uint32_t data);
//********************************************************************************

#endif
